import os
import re
import sys
import logging
import importlib
from copy import deepcopy
from fastapi import FastAPI
from os.path import dirname, abspath
from logging.config import dictConfig
from logging.handlers import RotatingFileHandler
BASE_DIR = dirname(abspath(__file__))
sys.path.insert(0, BASE_DIR)
from utils.dber import MongoDBer
from utils.singleton import Singleton
from config.environment import CONFIG
from config.logger import BASE_LOGGER, BASE_HANDLER, LOGGERS

@Singleton
class Server(object):
    def __init__(self, mode='development'):
        self.app_obj = FastAPI()
        self.router_module = self.router_file()
        self.init_logger()
        self.init_config(mode)
        self.init_dbase()
        self.register_router()

    def router_file(self):
        """ 获取路由文件名 """
        router_module = []
        router_root_path = os.path.join(BASE_DIR, 'app')
        for sub_dir in os.listdir(router_root_path):
            router_path = os.path.join(router_root_path, sub_dir)
            if not os.path.isdir(router_path):
                continue
            for module_name in os.listdir(router_path):
                if not re.match(r'[a-z][a-z_0-9]*\.py', module_name, re.I):
                    continue
                router_module.append(f'app.{sub_dir}.{module_name[:-3]}')
        return router_module

    def init_logger(self, ):
        """ 初始化日志 """
        # 路由日志配置
        for module_name in self.router_module:
            file_name = module_name.split('.')[-1]
            # 日志器
            cur_logger = deepcopy(BASE_LOGGER)
            cur_logger['handlers'] = [file_name + '_handler']
            LOGGERS['loggers'][file_name + '_logger'] = cur_logger
            # 处理器
            cur_handler = deepcopy(BASE_HANDLER)
            cur_handler['filename'] = os.path.join(BASE_DIR, 'logs', file_name + '.log')
            LOGGERS['handlers'][file_name + '_handler'] = cur_handler
        dictConfig(LOGGERS)
        logging.info('初始化：为路由添加日志配置！')

    def init_config(self, mode):
        """ 初始化：配置文件 """
        setattr(self.app_obj, "root_path", BASE_DIR)
        setattr(self.app_obj, 'config', CONFIG[mode])
        logging.info('初始化：项目配置文件和根路径！')

    def init_dbase(self):
        """ 初始化：数据库 """
        db_obj = {}
        db_dict = self.app_obj.config.DATABASES
        for db_name, db_url in db_dict.items():
            db_obj[db_name] = MongoDBer(db_url)
        logging.info('初始化：连接数据库！')
        setattr(self.app_obj, 'db_dict', db_obj)
    
    def register_router(self):
        """ 注册路由 """
        for module_name in self.router_module:
            cur_module = importlib.import_module(module_name)
            self.app_obj.include_router(cur_module.router)
        logging.info(f'完成路由注册，启动服务！')
        return self

# 全局日志配置
root_logger = logging.getLogger()
file_log_handler = RotatingFileHandler(
    BASE_DIR + "/logs/app.log", 
    maxBytes=1024 * 1024 * 30, 
    backupCount=10
)
formatter = logging.Formatter(
    fmt = "%(asctime)s [%(module)s:%(funcName)s:%(lineno)d] [%(levelname)s] %(message)s",
    datefmt= '%Y-%m-%d %H:%M:%S'
)
file_log_handler.setFormatter(formatter)
root_logger.addHandler(file_log_handler)
root_logger.setLevel(logging.INFO)

# 创建 FastAPI 对象
mode = os.environ.get('FAST_ENV', 'development')
app = Server(mode).register_router().app_obj